/**传统的创建对象的方式*/
var obj = {
    name:"孙悟空",
    age:18,
    sayHello:function () {
        console.log(this.name);
    }
};

var obj2 = {
    name:"猪八戒",
    age:28,
    sayHello:function () {
        console.log(this.name);
    }
};

var obj3 = {
    name:"沙和尚",
    age:38,
    sayHello:function () {
        console.log(this.name);
    }
};

obj3.sayHello();

console.log("-------------------------------");

/**使用工厂的方法创建对象， 通过该方法可以大批量的创建对象*/
function createPerson(name, age) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sayName = function () {
        console.log(this.name)
    };
    return obj;
}

var obj6 = createPerson("张无忌", 13);
var obj7 = createPerson("周芷若", 13);
var obj8 = createPerson("赵敏", 13);

obj6.sayName();

/**
 * 使用工厂方法创建的对象，使用的构造函数都是Object，所以创建的对象都是Object类型的，就导致我们无法区分出多种不同类型的对象
 * */


console.log("===========================构造函数===========================");

/**
 * 构造函数就是一个普通的函数，创建函数和普通的函数没有任何区别，不同的是构造函数习惯上首字母大写：
 *  function Person(){};
 *
 *  构造函数和普通函数的区别就是调用方式的不同，普通函数是直接调用，而构造函数需要使用new关键字来调用
 *
 *  构造函数的执行流程：
 *      1.立刻创建一个新的对象
 *      2. 将新建的对象设置为函数中的this， 在构造函数中可以使用this来引用新建的对象
 *      3. 逐行执行函数中的代码
 *      4. 将新建的对象作为返回值返回
 *
 *      使用同一个函数创建的对象，我们称之为一类对象，也将一个构造函数称之为一个类
 *      我们将通过一个构造函数创建的对象，称之为该类的实例。
 *
 *  this的情况：
 *      1. 当以函数调用时，this就是window
 *      2. 当以方法的形式调用时，谁调用方法this就是谁
 *      3. 当以构造函数的形式调用时，this就是新创建的那个对象
 * */

function Person(name, age) {

    this.name = name;
    this.age = age;
    this.say1 = function () {
        console.log(this.name);
    }

}
function Dog(name, age) {
    this.name = name;
    this.age = age;
    this.say1 = function () {
        console.log(this.name);
    }
}
/**使用普通方式来调用函数*/
var per = Person();

/*使用构造函数的方式来调用函数*/
var pe = new Person("孙悟空", 18);
pe.say1();

// console.log(per);
console.log(pe);

var dog = new Dog("旺财", 16);
console.log(dog);

/**
 * 使用instanceof可以检查一个对象是否是一个类的实例
 *  语法：
 *      对象 instanceof 构造函数
 *      如果是 返回true 否则返回 false
 * */

console.log(pe instanceof Person);
console.log(pe instanceof Dog);

console.log("---------------构造方法优化");

/**
 * 上面创建的Person构造函数中，为每一个对象都添加加了一个say1方法
 * 目前我们的方法是在构造函数内部创建的，也就是构造函数每执行一次就会创建一个新的say1方法，也就是所有实例的say1都是唯一的。
 * 这样就导致了构造函数执行一次就会创建一个新的方法，执行10000次就会创建10000个新的方法。
 *
 * 解决办法：将此方法定义为全局的方法(将函数定义在全局作用域中，污染了全局作用域的命名空间，而且定义在全局作用域中也很不安全)
 * */

function Pers(name, age){
    this.name = name;
    this.age = age;
    this.say2 = fun;

}

function fun() {
    console.log(this.name);
}

var ss = new Pers("Tom", 18);
console.log(ss.say2);

